home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 June / CHIP Haziran 2001.iso / prog / haziran / 19 / setup.exe / data.z / altera_lib.c < prev    next >
C/C++ Source or Header  |  2001-04-11  |  19KB  |  610 lines

  1. //////////////////////////////////////////////////////////////////////
  2. // File - altera_lib.c
  3. //
  4. // Library for accessing the ALTERA card.
  5. // Code was generated by Driver Wizard.
  6. // It accesses the hardware via WinDriver functions.
  7. // 
  8. //////////////////////////////////////////////////////////////////////
  9.  
  10. #include "altera_lib.h"
  11. #include "../../../include/windrvr_int_thread.h"
  12. #include <stdio.h>
  13.  
  14. // this string is set to an error message, if one occurs
  15. CHAR ALTERA_ErrorString[1024];
  16.  
  17. // internal data structures
  18. typedef struct
  19. {
  20.     WD_INTERRUPT Int;
  21.     HANDLE hThread;
  22.     WD_TRANSFER Trans[1];
  23.     ALTERA_INT_HANDLER funcIntHandler;
  24. } ALTERA_INT_INTERRUPT;
  25.  
  26. typedef struct
  27. {
  28.     DWORD index;
  29.     DWORD dwMask;
  30.     BOOL  fIsMemory;
  31.     BOOL  fActive;
  32. } ALTERA_ADDR_DESC;
  33.  
  34. typedef struct ALTERA_STRUCT
  35. {
  36.     HANDLE hWD;
  37.     BOOL   fUseInt;
  38.     ALTERA_INT_INTERRUPT Int;
  39.     WD_PCI_SLOT pciSlot;
  40.     ALTERA_ADDR_DESC addrDesc[ALTERA_ITEMS];
  41.     WD_CARD_REGISTER cardReg;
  42. } ALTERA_STRUCT;
  43.  
  44. // internal function used by ALTERA_Open()
  45. BOOL ALTERA_DetectCardElements(ALTERA_HANDLE hALTERA);
  46.  
  47. DWORD ALTERA_CountCards (DWORD dwVendorID, DWORD dwDeviceID)
  48. {
  49.     WD_VERSION ver;
  50.     WD_PCI_SCAN_CARDS pciScan;
  51.     HANDLE hWD = INVALID_HANDLE_VALUE;
  52.  
  53.     ALTERA_ErrorString[0] = '\0';
  54.     hWD = WD_Open();
  55.     // check if handle valid & version OK
  56.     if (hWD==INVALID_HANDLE_VALUE) 
  57.     {
  58.         sprintf( ALTERA_ErrorString, "Failed opening " WD_PROD_NAME " device\n");
  59.         return 0;
  60.     }
  61.  
  62.     BZERO(ver);
  63.     WD_Version(hWD,&ver);
  64.     if (ver.dwVer<WD_VER) 
  65.     {
  66.         sprintf( ALTERA_ErrorString, "Incorrect " WD_PROD_NAME " version\n");
  67.         WD_Close (hWD);
  68.         return 0;
  69.     }
  70.  
  71.     BZERO(pciScan);
  72.     pciScan.searchId.dwVendorId = dwVendorID;
  73.     pciScan.searchId.dwDeviceId = dwDeviceID;
  74.     WD_PciScanCards (hWD, &pciScan);
  75.     WD_Close (hWD);
  76.     if (pciScan.dwCards==0)
  77.         sprintf( ALTERA_ErrorString, "no cards found\n");
  78.     return pciScan.dwCards;
  79. }
  80.  
  81. BOOL ALTERA_Open (ALTERA_HANDLE *phALTERA, DWORD dwVendorID, DWORD dwDeviceID, DWORD nCardNum, DWORD options)
  82. {
  83.     ALTERA_HANDLE hALTERA = (ALTERA_HANDLE) malloc (sizeof (ALTERA_STRUCT));
  84.  
  85.     WD_VERSION ver;
  86.     WD_PCI_SCAN_CARDS pciScan;
  87.     WD_PCI_CARD_INFO pciCardInfo;
  88.  
  89.     *phALTERA = NULL;
  90.     ALTERA_ErrorString[0] = '\0';
  91.    BZERO(*hALTERA);
  92.  
  93.     hALTERA->hWD = WD_Open();
  94.  
  95.     // check if handle valid & version OK
  96.     if (hALTERA->hWD==INVALID_HANDLE_VALUE)
  97.     {
  98.         sprintf( ALTERA_ErrorString, "Failed opening " WD_PROD_NAME " device\n");
  99.         goto Exit;
  100.     }
  101.  
  102.     BZERO(ver);
  103.     WD_Version(hALTERA->hWD,&ver);
  104.     if (ver.dwVer<WD_VER)
  105.     {
  106.         sprintf( ALTERA_ErrorString, "Incorrect " WD_PROD_NAME " version\n");
  107.         goto Exit;
  108.     }
  109.  
  110.     BZERO(pciScan);
  111.     pciScan.searchId.dwVendorId = dwVendorID;
  112.     pciScan.searchId.dwDeviceId = dwDeviceID;
  113.     WD_PciScanCards (hALTERA->hWD, &pciScan);
  114.     if (pciScan.dwCards==0) // Found at least one card
  115.     {
  116.         sprintf( ALTERA_ErrorString, "Could not find PCI card\n");
  117.         goto Exit;
  118.     }
  119.     if (pciScan.dwCards<=nCardNum)
  120.     {
  121.         sprintf( ALTERA_ErrorString, "Card out of range of available cards\n");
  122.         goto Exit;
  123.     }
  124.  
  125.     BZERO(pciCardInfo);
  126.     pciCardInfo.pciSlot = pciScan.cardSlot[nCardNum];
  127.     WD_PciGetCardInfo (hALTERA->hWD, &pciCardInfo);
  128.     hALTERA->pciSlot = pciCardInfo.pciSlot;
  129.     hALTERA->cardReg.Card = pciCardInfo.Card;
  130.  
  131.     hALTERA->fUseInt = (options & ALTERA_OPEN_USE_INT) ? TRUE : FALSE;
  132.     if (!hALTERA->fUseInt)
  133.     {
  134.         DWORD i;
  135.         // Remove interrupt item if not needed
  136.         for (i=0; i<hALTERA->cardReg.Card.dwItems; i++)
  137.         {
  138.             WD_ITEMS *pItem = &hALTERA->cardReg.Card.Item[i];
  139.             if (pItem->item==ITEM_INTERRUPT)
  140.                 pItem->item = ITEM_NONE;
  141.         }
  142.     }
  143.     else
  144.     {
  145.         DWORD i;
  146.         // make interrupt resource sharable
  147.         for (i=0; i<hALTERA->cardReg.Card.dwItems; i++)
  148.         {
  149.             WD_ITEMS *pItem = &hALTERA->cardReg.Card.Item[i];
  150.             if (pItem->item==ITEM_INTERRUPT)
  151.                 pItem->fNotSharable = FALSE;
  152.         }
  153.     }
  154.  
  155.     hALTERA->cardReg.fCheckLockOnly = FALSE;
  156.     WD_CardRegister (hALTERA->hWD, &hALTERA->cardReg);
  157.     if (hALTERA->cardReg.hCard==0)
  158.     {
  159.         sprintf ( ALTERA_ErrorString, "Failed locking device.\n");
  160.         goto Exit;
  161.     }
  162.  
  163.     if (!ALTERA_DetectCardElements(hALTERA))
  164.     {
  165.         sprintf ( ALTERA_ErrorString, "Card does not have all items expected for ALTERA\n");
  166.         goto Exit;
  167.     }
  168.  
  169.     // Open finished OK
  170.     *phALTERA = hALTERA;
  171.     return TRUE;
  172.  
  173. Exit:
  174.     // Error during Open
  175.     if (hALTERA->cardReg.hCard) 
  176.         WD_CardUnregister(hALTERA->hWD, &hALTERA->cardReg);
  177.     if (hALTERA->hWD!=INVALID_HANDLE_VALUE)
  178.         WD_Close(hALTERA->hWD);
  179.     free (hALTERA);
  180.     return FALSE;
  181. }
  182.  
  183. void ALTERA_Close(ALTERA_HANDLE hALTERA)
  184. {
  185.     // disable interrupts
  186.     if (ALTERA_IntIsEnabled(hALTERA))
  187.         ALTERA_IntDisable(hALTERA);
  188.  
  189.     // unregister card
  190.     if (hALTERA->cardReg.hCard) 
  191.         WD_CardUnregister(hALTERA->hWD, &hALTERA->cardReg);
  192.  
  193.     // close WinDriver
  194.     WD_Close(hALTERA->hWD);
  195.  
  196.     free (hALTERA);
  197. }
  198.  
  199. void ALTERA_WritePCIReg(ALTERA_HANDLE hALTERA, DWORD dwReg, DWORD dwData)
  200. {
  201.     WD_PCI_CONFIG_DUMP pciCnf;
  202.  
  203.     BZERO(pciCnf);
  204.     pciCnf.pciSlot = hALTERA->pciSlot;
  205.     pciCnf.pBuffer = &dwData;
  206.     pciCnf.dwOffset = dwReg;
  207.     pciCnf.dwBytes = 4;
  208.     pciCnf.fIsRead = FALSE;
  209.     WD_PciConfigDump(hALTERA->hWD,&pciCnf);
  210. }
  211.  
  212. DWORD ALTERA_ReadPCIReg(ALTERA_HANDLE hALTERA, DWORD dwReg)
  213. {
  214.     WD_PCI_CONFIG_DUMP pciCnf;
  215.     DWORD dwVal;
  216.  
  217.     BZERO(pciCnf);
  218.     pciCnf.pciSlot = hALTERA->pciSlot;
  219.     pciCnf.pBuffer = &dwVal;
  220.     pciCnf.dwOffset = dwReg;
  221.     pciCnf.dwBytes = 4;
  222.     pciCnf.fIsRead = TRUE;
  223.     WD_PciConfigDump(hALTERA->hWD,&pciCnf);
  224.     return dwVal;
  225. }
  226.  
  227. void ALTERA_WritePCIRegN(ALTERA_HANDLE hALTERA, DWORD dwReg, DWORD dwData, DWORD dwBytes)
  228. {
  229.     WD_PCI_CONFIG_DUMP pciCnf;
  230.  
  231.     BZERO(pciCnf);
  232.     pciCnf.pciSlot = hALTERA->pciSlot;
  233.     pciCnf.pBuffer = &dwData;
  234.     pciCnf.dwOffset = dwReg;
  235.     pciCnf.dwBytes = dwBytes;
  236.     pciCnf.fIsRead = FALSE;
  237.     WD_PciConfigDump(hALTERA->hWD,&pciCnf);
  238. }
  239.  
  240. DWORD ALTERA_ReadPCIRegN(ALTERA_HANDLE hALTERA, DWORD dwReg, DWORD dwBytes)
  241. {
  242.     WD_PCI_CONFIG_DUMP pciCnf;
  243.     DWORD dwVal = 0;
  244.  
  245.     BZERO(pciCnf);
  246.     pciCnf.pciSlot = hALTERA->pciSlot;
  247.     pciCnf.pBuffer = &dwVal;
  248.     pciCnf.dwOffset = dwReg;
  249.     pciCnf.dwBytes = dwBytes;
  250.     pciCnf.fIsRead = TRUE;
  251.     WD_PciConfigDump(hALTERA->hWD,&pciCnf);
  252.     return dwVal;
  253. }
  254.  
  255. BOOL ALTERA_DetectCardElements(ALTERA_HANDLE hALTERA)
  256. {
  257.     DWORD i;
  258.     DWORD ad_sp;
  259.  
  260.     BZERO(hALTERA->Int);
  261.     BZERO(hALTERA->addrDesc);
  262.  
  263.     for (i=0; i<hALTERA->cardReg.Card.dwItems; i++)
  264.     {
  265.         WD_ITEMS *pItem = &hALTERA->cardReg.Card.Item[i];
  266.  
  267.         switch (pItem->item)
  268.         {
  269.         case ITEM_MEMORY:
  270.         case ITEM_IO:
  271.             {
  272.                 DWORD dwBytes;
  273.                 DWORD dwPhysAddr;
  274.                 BOOL fIsMemory;
  275.                 if (pItem->item==ITEM_MEMORY)
  276.                 {
  277.                     dwBytes = pItem->I.Mem.dwBytes;
  278.                     dwPhysAddr = pItem->I.Mem.dwPhysicalAddr;
  279.                     fIsMemory = TRUE;
  280.                 }
  281.                 else 
  282.                 {
  283.                     dwBytes = pItem->I.IO.dwBytes;
  284.                     dwPhysAddr = pItem->I.IO.dwAddr & 0xffff;
  285.                     fIsMemory = FALSE;
  286.                 }
  287.  
  288.                 for (ad_sp=0; ad_sp<ALTERA_ITEMS; ad_sp++)
  289.                 {
  290.                     DWORD dwPCIAddr;
  291.                     DWORD dwPCIReg;
  292.  
  293.                     if (ALTERA_IsAddrSpaceActive(hALTERA, (ALTERA_ADDR) ad_sp)) continue;
  294.                     if (ad_sp<ALTERA_AD_EPROM) dwPCIReg = PCI_BAR0 + 4*ad_sp;
  295.                     else dwPCIReg = PCI_ERBAR;
  296.                     dwPCIAddr = ALTERA_ReadPCIReg(hALTERA, dwPCIReg);
  297.                     if (dwPCIAddr & 1)
  298.                     {
  299.                         if (fIsMemory) continue;
  300.                         dwPCIAddr &= ~0x3;
  301.                     }
  302.                     else
  303.                     {
  304.                         if (!fIsMemory) continue;
  305.                         dwPCIAddr &= ~0xf;
  306.                     }
  307.                     if (dwPCIAddr==dwPhysAddr)
  308.                         break;
  309.                 }
  310.                 if (ad_sp<ALTERA_ITEMS)
  311.                 {
  312.                     DWORD j;
  313.                     hALTERA->addrDesc[ad_sp].fActive = TRUE;
  314.                     hALTERA->addrDesc[ad_sp].index = i;
  315.                     hALTERA->addrDesc[ad_sp].fIsMemory = fIsMemory;
  316.                     hALTERA->addrDesc[ad_sp].dwMask = 0;
  317.                     for (j=1; j<dwBytes && j!=0x80000000; j *= 2)
  318.                     {
  319.                         hALTERA->addrDesc[ad_sp].dwMask = 
  320.                             (hALTERA->addrDesc[ad_sp].dwMask << 1) | 1;
  321.                     }
  322.                 }
  323.             }
  324.             break;
  325.         case ITEM_INTERRUPT:
  326.             if (hALTERA->Int.Int.hInterrupt) return FALSE;
  327.             hALTERA->Int.Int.hInterrupt = pItem->I.Int.hInterrupt;
  328.             break;
  329.         }
  330.     }
  331.  
  332.     // check that all the items needed were found
  333.     // check if interrupt found
  334.     if (hALTERA->fUseInt && !hALTERA->Int.Int.hInterrupt) 
  335.     {
  336.         return FALSE;
  337.     }
  338.  
  339.     // check that at least one memory space was found
  340.     for (i = 0; i<ALTERA_ITEMS; i++)
  341.         if (ALTERA_IsAddrSpaceActive(hALTERA, (ALTERA_ADDR) i)) break;
  342.     if (i==ALTERA_ITEMS) return FALSE;
  343.  
  344.     return TRUE;
  345. }
  346.  
  347. BOOL ALTERA_IsAddrSpaceActive(ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace)
  348. {
  349.     return hALTERA->addrDesc[addrSpace].fActive;
  350. }
  351.  
  352. void ALTERA_GetPciSlot(ALTERA_HANDLE hALTERA, WD_PCI_SLOT *pPciSlot)
  353. {
  354.     memcpy((PVOID)pPciSlot, &(hALTERA->pciSlot), sizeof(WD_PCI_SLOT));
  355. }
  356.  
  357. // General read/write function
  358. void ALTERA_ReadWriteBlock(ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, BOOL fRead, PVOID buf, DWORD dwBytes, ALTERA_MODE mode)
  359. {
  360.     WD_TRANSFER trans;
  361.     BOOL fMem = hALTERA->addrDesc[addrSpace].fIsMemory;
  362.     // safty check: is the address range active
  363.     if (!ALTERA_IsAddrSpaceActive(hALTERA, addrSpace)) return;
  364.     BZERO(trans);
  365.     if (fRead)
  366.     {
  367.         if (mode==ALTERA_MODE_BYTE) trans.cmdTrans = fMem ? RM_SBYTE : RP_SBYTE;
  368.         else if (mode==ALTERA_MODE_WORD) trans.cmdTrans = fMem ? RM_SWORD : RP_SWORD;
  369.         else if (mode==ALTERA_MODE_DWORD) trans.cmdTrans = fMem ? RM_SDWORD : RP_SDWORD;
  370.     }
  371.     else
  372.     {
  373.         if (mode==ALTERA_MODE_BYTE) trans.cmdTrans = fMem ? WM_SBYTE : WP_SBYTE;
  374.         else if (mode==ALTERA_MODE_WORD) trans.cmdTrans = fMem ? WM_SWORD : WP_SWORD;
  375.         else if (mode==ALTERA_MODE_DWORD) trans.cmdTrans = fMem ? WM_SDWORD : WP_SDWORD;
  376.     }
  377.     if (fMem)
  378.         trans.dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwTransAddr;
  379.     else trans.dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.IO.dwAddr;
  380.     trans.dwPort += dwOffset;
  381.  
  382.     trans.fAutoinc = TRUE;
  383.     trans.dwBytes = dwBytes;
  384.     trans.dwOptions = 0;
  385.     trans.Data.pBuffer = buf;
  386.     WD_Transfer (hALTERA->hWD, &trans);
  387. }
  388.  
  389. BYTE ALTERA_ReadByte (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
  390. {
  391.     BYTE data;
  392.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  393.     {
  394.         PBYTE pData = (PBYTE) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  395.         data = *pData; // read from the memory mapped range directly
  396.     }
  397.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (BYTE), ALTERA_MODE_BYTE);
  398.     return data;
  399. }
  400.  
  401. WORD ALTERA_ReadWord (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
  402. {
  403.     WORD data;
  404.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  405.     {
  406.         PWORD pData = (PWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  407.         data = *pData; // read from the memory mapped range directly
  408.     }
  409.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (WORD), ALTERA_MODE_WORD);
  410.     return data;
  411. }
  412.  
  413. DWORD ALTERA_ReadDword (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
  414. {
  415.     DWORD data;
  416.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  417.     {
  418.         PDWORD pData = (PDWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  419.         data = *pData; // read from the memory mapped range directly
  420.     }
  421.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (DWORD), ALTERA_MODE_DWORD);
  422.     return data;
  423. }
  424.  
  425. void ALTERA_WriteByte (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, BYTE data)
  426. {
  427.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  428.     {
  429.         PBYTE pData = (PBYTE) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  430.         *pData = data; // write to the memory mapped range directly
  431.     }
  432.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (BYTE), ALTERA_MODE_BYTE);
  433. }
  434.  
  435. void ALTERA_WriteWord (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, WORD data)
  436. {
  437.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  438.     {
  439.         PWORD pData = (PWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  440.         *pData = data; // write to the memory mapped range directly
  441.     }
  442.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (WORD), ALTERA_MODE_WORD);
  443. }
  444.  
  445. void ALTERA_WriteDword (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, DWORD data)
  446. {
  447.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  448.     {
  449.         PDWORD pData = (PDWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
  450.         *pData = data; // write to the memory mapped range directly
  451.     }
  452.     else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (DWORD), ALTERA_MODE_DWORD);
  453. }
  454.  
  455. BOOL ALTERA_IntIsEnabled (ALTERA_HANDLE hALTERA)
  456. {
  457.     if (!hALTERA->fUseInt) return FALSE;
  458.     if (!hALTERA->Int.hThread) return FALSE;
  459.     return TRUE;
  460. }
  461.  
  462. void ALTERA_IntHandler (PVOID pData)
  463. {
  464.     ALTERA_HANDLE hALTERA = (ALTERA_HANDLE) pData;
  465.     ALTERA_INT_RESULT intResult;
  466.     intResult.dwCounter = hALTERA->Int.Int.dwCounter;
  467.     intResult.dwLost = hALTERA->Int.Int.dwLost;
  468.     intResult.fStopped = hALTERA->Int.Int.fStopped;
  469.     hALTERA->Int.funcIntHandler(hALTERA, &intResult);
  470. }
  471.  
  472. BOOL ALTERA_IntEnable (ALTERA_HANDLE hALTERA, ALTERA_INT_HANDLER funcIntHandler)
  473. {
  474.     ALTERA_ADDR addrSpace;
  475.  
  476.     if (!hALTERA->fUseInt) return FALSE;
  477.     // check if interrupt is already enabled
  478.     if (hALTERA->Int.hThread) return FALSE;
  479.  
  480.     BZERO(hALTERA->Int.Trans);
  481.     // This is a sample of handling interrupts:
  482.     // One transfer command is issued to CANCEL the source of the interrupt,
  483.     // otherwise, the PC will hang when an interrupt occurs!
  484.     // You will need to modify this code to fit your specific hardware.
  485.     addrSpace = ALTERA_AD_BAR0; // put the address space of the register here
  486.     if (hALTERA->addrDesc[addrSpace].fIsMemory)
  487.     {
  488.         hALTERA->Int.Trans[0].dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwTransAddr;
  489.         hALTERA->Int.Trans[0].cmdTrans = WM_DWORD;
  490.     }
  491.     else
  492.     {
  493.         hALTERA->Int.Trans[0].dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.IO.dwAddr;
  494.         hALTERA->Int.Trans[0].cmdTrans = WP_DWORD;
  495.     }
  496.     hALTERA->Int.Trans[0].dwPort += 0; // put the offset of the register from the beginning of the address space here
  497.     hALTERA->Int.Trans[0].Data.Dword = 0x0;
  498.     hALTERA->Int.Int.dwCmds = 1;
  499.     hALTERA->Int.Int.Cmd = hALTERA->Int.Trans;
  500.     hALTERA->Int.Int.dwOptions |= INTERRUPT_CMD_COPY;
  501.  
  502.     // this calls WD_IntEnable() and creates an interrupt handler thread
  503.     hALTERA->Int.funcIntHandler = funcIntHandler;
  504.     if (!InterruptThreadEnable(&hALTERA->Int.hThread, hALTERA->hWD, &hALTERA->Int.Int, ALTERA_IntHandler, (PVOID) hALTERA))
  505.         return FALSE;
  506.  
  507.     return TRUE;
  508. }
  509.  
  510. void ALTERA_IntDisable (ALTERA_HANDLE hALTERA)
  511. {
  512.     if (!hALTERA->fUseInt) return;
  513.     if (!hALTERA->Int.hThread) return;
  514.  
  515.     // this calls WD_IntDisable()
  516.     InterruptThreadDisable(hALTERA->Int.hThread);
  517.  
  518.     hALTERA->Int.hThread = NULL;
  519. }
  520.  
  521. BOOL ALTERA_DMAWait(ALTERA_HANDLE hALTERA)
  522. {
  523.     BOOL fOk = FALSE;
  524.     DWORD i = 10*1000*1000/2; // wait 10 seconds (each loop waits 2 microseconds
  525.     for(;i;i--)
  526.     {
  527.         DWORD dwDMAISR = ALTERA_ReadDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMAISR);
  528.         WD_SLEEP sleep;
  529.            if (dwDMAISR & TX_COMP)
  530.         {
  531.             fOk = TRUE;
  532.             break;
  533.         }
  534.  
  535.         if (dwDMAISR & ERROR_PENDING) 
  536.         {
  537.             sprintf(ALTERA_ErrorString, "hardware dma failure\n");
  538.             break;
  539.         }
  540.         BZERO(sleep);
  541.         sleep.dwMicroSeconds = 2;
  542.         WD_Sleep(hALTERA->hWD, &sleep);
  543.     }
  544.     if (!i)
  545.         sprintf(ALTERA_ErrorString, "dma transfer timeout\n");
  546.  
  547.     return fOk;
  548. }
  549.  
  550. BOOL ALTERA_DMAReadWriteBlock(ALTERA_HANDLE hALTERA, DWORD dwLocalAddr, PVOID pBuffer, BOOL fRead, DWORD dwBytes, BOOL fChained)
  551. {
  552.     BOOL fOk = FALSE;
  553.     WD_DMA dma;
  554.     DWORD DMACsr;
  555.     DWORD i;
  556.  
  557.     if (dwBytes == 0)
  558.         return fOk;
  559.     BZERO(dma);
  560.     dma.pUserAddr = pBuffer;
  561.     dma.dwBytes = dwBytes;
  562.     dma.dwOptions = 0;
  563.     WD_DMALock(hALTERA->hWD, &dma);
  564.     if (!dma.hDma)
  565.     {
  566.         sprintf(ALTERA_ErrorString, "cannot lock down buffer\n");
  567.         return FALSE;
  568.     }
  569.     DMACsr = fRead ? DIRECTION : 0;
  570.     DMACsr |= DMA_ENABLE | TRXCOMPINTDIS | INTERRUPT_ENABLE;
  571.     if (dma.dwPages>ALTERA_DMA_FIFO_REGS)
  572.     {
  573.         sprintf(ALTERA_ErrorString, "too many pages for chain transfer\n");
  574.         // not enough pages
  575.         goto Exit;
  576.     }
  577.     if (fChained)
  578.     {
  579.         DMACsr |= CHAINEN;
  580.         for (i=0;i<dma.dwPages;i++)
  581.         {
  582.             ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, FIFO_BASE_OFFSET, (DWORD) dma.Page[i].pPhysicalAddr);
  583.             ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, FIFO_BASE_OFFSET, dma.Page[i].dwBytes);
  584.         }
  585.         ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMALAR, dwLocalAddr);
  586.         ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMACSR, DMACsr); //this starts the dma
  587.         fOk = ALTERA_DMAWait(hALTERA);
  588.     }
  589.     else
  590.     {
  591.         DWORD dwTotalBytes = 0;
  592.         ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMACSR, DMACsr);
  593.         for (i=0;i<dma.dwPages;i++)
  594.         {
  595.             ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMALAR, dwLocalAddr+dwTotalBytes);
  596.             ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMABCR, dma.Page[i].dwBytes);
  597.             ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMAACR, (DWORD) dma.Page[i].pPhysicalAddr); // this starts the dma
  598.             fOk = ALTERA_DMAWait(hALTERA);
  599.             if (!fOk)
  600.                 break;
  601.             dwTotalBytes += dma.Page[i].dwBytes;
  602.         }
  603.  
  604.     }
  605.  
  606. Exit:
  607.      WD_DMAUnlock(hALTERA->hWD, &dma);
  608.      return fOk;
  609. }    
  610.